<?php

use Overtrue\EasySms\EasySms;

/**
 * 文件上传方法
 * @param \App\Http\Requests\FileRequest $request
 * @param int $identity
 * @return bool|mixed
 */
function upload(\App\Http\Controllers\Common\FileRequest $request, $identity = 1)
{
    $fileModel = new \App\Models\File();
    try {
        //存储文件名称;
        $storeName = $request->file->hashName();
        $path = 'uploads/'. date('Y').'/'.date('m').'/'.date('d');
        switch ($identity) {
            case 1:// 头像
                $path = date('Y').'/'.date('m').'/'.date('d');
                $path = 'avatar/' . $path;

                break;
            case 2: // 后台
                $id = Auth::guard('admin')->id();

                if ($id) {
                    if (!$path) {
                        $path = date('Y').'/'.date('m').'/'.date('d');
                        $path = 'admin/'. $id . '/' . $path;
                    }
                };
                $fileModel->type    = 1;
                $fileModel->info_id = $id;
                break;
            case 3:  // excel 上传
                $path = date('Y').'/'.date('m').'/'.date('d');

                $path = 'excel/' . $path;

                break;
            default: // 其他
                $path = date('Y').'/'.date('m').'/'.date('d');

                $path = 'other/' . $path;
                break;
        }
        $request->file->storeAs($path, $storeName);

        $fileModel->name = $storeName;

        $fileModel->path = "{$path}/{$storeName}";

        $fileModel->mime_type = $request->file->getClientMimeType();

        $fileModel->origin_name = $request->file->getClientOriginalName();

        $fileModel->extension = $request->file->extension();

        if ($fileModel->save()) {
            if (isset($request->upfile)) {
                $resArray = array(
                    'state' => 'SUCCESS',
                    'url' => IMAGE_PATH . '/' . $fileModel->path,
                    'type' => $request->file->extension,
                    'title' => $storeName,
                    'original' => $storeName,
                );
                return json_encode($resArray);
            } else {
                return ['id'=>$fileModel->id,'path'=>$fileModel->path];
            }

        }
    }catch (\Exception $exception) {

        report($exception);
        return $exception->getMessage();
        //return false;
    }

    return false;
}

/**
 * 视频上传
 * @param $request
 * @return bool|mixed
 */
function upload_media($request){
    $fileModel = new \App\Models\File();

    try {
        //存储文件名称;
        $storeName = $request->file->hashName();

        $upload_path = date('Y').'/'.date('m').'/'.date('d');

        if (isset(auth('admin')->user()->id)) {
            $id = auth('admin')->user()->id;
            $upload_path = 'uploads/media/'. $id . '/' . $upload_path;
        }else{
            $upload_path = 'uploads/media/'.$upload_path;
        }

        //$request->file->storeAs($path, $storeName);
        // 获取文件本地路径
        $path = $request->file->getRealPath();
        $result = \App\Services\OSS::upload($upload_path.'/'.$storeName,$path);
        //dd($result);
        $real_name = $upload_path.'/'.$storeName;

        $fileModel->name = $real_name;

        //$fileModel->path = "{$path}/{$storeName}";

        $path = \App\Services\OSS::getUrl($real_name);

        $path = explode(':',$path);

        $fileModel->path = $path[1];

        //$fileModel->path =  \App\Services\OSS::getUrl($real_name);

        $fileModel->mime = $request->file->getClientMimeType();

        $fileModel->origin_name = $request->file->getClientOriginalName();

        $fileModel->extension = $request->file->extension();

        if ($fileModel->save()) {
            return  $fileModel->id;
        }
    }catch (\Exception $exception) {

        report($exception);

        return false;
    }

    return false;
}

/**
 * 创建多级目录
 * @param $path string 要创建的目录
 * @param $mode int 创建目录的模式，在windows下可忽略
 * @return string
 */
function create_dir($path, $mode = 0777)
{
    if (is_dir($path)) {
        # 如果目录已经存在，则不创建
        return "该目录已经存在";
    } else {
        # 不存在，创建
        if (mkdir($path, $mode, true)) {
            return "创建目录成功";
        } else {
            return "创建目录失败";
        }
    }
}

/**
 * 数据重组方法
 * @param $lists array() 数据数组
 * @return $data Array() 返回重组后的数组数据
 */
function ArrFor($lists=[])
{
    // 让id 键值反转 组成一维数组
    $pid_map_id = array_flip(array_column($lists,'id'));
    $data = [];
    foreach ($lists as $k=>$list){
        if($list['pid'] == 0){
            array_push($data,$lists[$k]);
        }else{
            /*
            $list['pid']; //父级ID
            $pid_map_id[$list['pid']]; // 父级数据所在的索引
            $lists[$pid_map_id[$list['pid']]]; //父级数据
            */
            if(!key_exists('childs',$lists[$pid_map_id[$list['pid']]])){
                $lists[$pid_map_id[$list['pid']]]['childs']=[];
            }
            $lists[$pid_map_id[$list['pid']]]['childs'][] = $lists[$k];
        }
    }
    return $data;
}

/**
 * 权限按钮显示判断方法
 * @param $data 当前所有权限路由
 * @param $route 对比的路由
 * @return boolean  true|false
 */
function AdminPermission()
{
    $data = session()->get('AdminPermissions');
    if (isset($data['data'])) {
        return $data['data'];
    }
    return $data;
}

/**
 * 二维数组根据首字母分组排序
 * @param  array $data 二维数组
 * @param  string $targetKey 首字母的键名
 * @return array             根据首字母关联的二维数组
 */
function groupByInitials(array $data, $targetKey = 'brand')
{
    $data = array_map(function ($item) use ($targetKey) {
        return array_merge($item, [
            'initials' => getInitials($item[$targetKey]),
        ]);
    }, $data);
    $data = sortInitials($data);
    return $data;
}

/**
 * 获取首字母
 * @param  string $str 汉字字符串
 * @return string 首字母
 */
function getInitials($str)
{
    if (empty($str)) {
        return '';
    }
    $fchar = ord($str{0});
    if ($fchar >= ord('A') && $fchar <= ord('z')) {
        return strtoupper($str{0});
    }

    $s1 = iconv('UTF-8', 'gb2312', $str);
    $s2 = iconv('gb2312', 'UTF-8', $s1);
    $s = $s2 == $str ? $s1 : $str;
    $asc = ord($s{0}) * 256 + ord($s{1}) - 65536;
    if ($asc >= -20319 && $asc <= -20284) {
        return 'A';
    }

    if ($asc >= -20283 && $asc <= -19776) {
        return 'B';
    }

    if ($asc >= -19775 && $asc <= -19219) {
        return 'C';
    }

    if ($asc >= -19218 && $asc <= -18711) {
        return 'D';
    }

    if ($asc >= -18710 && $asc <= -18527) {
        return 'E';
    }

    if ($asc >= -18526 && $asc <= -18240) {
        return 'F';
    }

    if ($asc >= -18239 && $asc <= -17923) {
        return 'G';
    }

    if ($asc >= -17922 && $asc <= -17418) {
        return 'H';
    }

    if ($asc >= -17417 && $asc <= -16475) {
        return 'J';
    }

    if ($asc >= -16474 && $asc <= -16213) {
        return 'K';
    }

    if ($asc >= -16212 && $asc <= -15641) {
        return 'L';
    }

    if ($asc >= -15640 && $asc <= -15166) {
        return 'M';
    }

    if ($asc >= -15165 && $asc <= -14923) {
        return 'N';
    }

    if ($asc >= -14922 && $asc <= -14915) {
        return 'O';
    }

    if ($asc >= -14914 && $asc <= -14631) {
        return 'P';
    }

    if ($asc >= -14630 && $asc <= -14150) {
        return 'Q';
    }

    if ($asc >= -14149 && $asc <= -14091) {
        return 'R';
    }

    if ($asc >= -14090 && $asc <= -13319) {
        return 'S';
    }

    if ($asc >= -13318 && $asc <= -12839) {
        return 'T';
    }

    if ($asc >= -12838 && $asc <= -12557) {
        return 'W';
    }

    if ($asc >= -12556 && $asc <= -11848) {
        return 'X';
    }

    if ($asc >= -11847 && $asc <= -11056) {
        return 'Y';
    }

    if ($asc >= -11055 && $asc <= -10247) {
        return 'Z';
    }
    return null;
}

/**
 * 按字母排序
 * @param  array $data
 * @return array
 */
function sortInitials(array $data)
{
    $sortData = [];
    foreach ($data as $key => $value) {
        $sortData[$value['initials']][] = $value;
    }
    ksort($sortData);
    return $sortData;
}

/**
 * 权限按钮显示判断方法
 * @param $route 对比的路由
 * @return boolean  true|false
 */
function PermissionOperator($route)
{

    $data = session()->get('AdminPermissions')['routes'];
    $route2 = '/'.$route;

    if(is_array($data)){
        if (in_array($route, $data) || in_array($route2, $data)) {
            return true;
        }
    }

    return false;
}

// 删除图片
function deleteFile($path){
    if (\Illuminate\Support\Facades\Storage::exists($path)) {
        $re = \Illuminate\Support\Facades\Storage::delete($path);
        if ($re) {
            // 删除数据库文件
            File::where('path',$path)->delete();
        }
    }
    return true;
}


/**
 * 生成全局id
 * @return string 返回
 **/
function guid( $opt = false ){
    if( function_exists('com_create_guid') ){
        if( $opt ){
            return com_create_guid();
        } else {
            return trim( com_create_guid(), '{}' );
        }
    } else {
        mt_srand( (double)microtime() * 10000 );
        $charid = strtoupper( md5(uniqid(rand(), true)) );
        $hyphen = chr( 45 );    // "-"
        $left_curly = $opt ? chr(123) : "";     //  "{"
        $right_curly = $opt ? chr(125) : "";    //  "}"
        $uuid = $left_curly
            . substr( $charid, 0, 8 ) . $hyphen
            . substr( $charid, 8, 4 ) . $hyphen
            . substr( $charid, 12, 4 ) . $hyphen
            . substr( $charid, 16, 4 ) . $hyphen
            . substr( $charid, 20, 12 )
            . $right_curly;
        return $uuid;
    }
}

/**
 * 发送系统通知用户(指定用户)
 * @param \App\Models\User $user 模型
 * @param string $title 标题
 * @param string $content 内容
 * @param array $extend 扩展参数
 * @author john1668@qq.com
 */
function sendSystemNoticeForUser($user, $title, $content, $extend = [])
{
    try{

        $message = new \App\Notifications\Messages\UserNotificationMessage($title, $content, $extend);

        \Illuminate\Support\Facades\Notification::send($user, new \App\Notifications\UserNotification($message, false));

    } catch (\Exception $exception) {

        \report($exception);
    }

}

/**
 * 发送系统通知用户(指定供应商)
 * @param \App\Models\User $user 模型
 * @param string $title 标题
 * @param string $content 内容
 * @param array $extend 扩展参数
 * @author john1668@qq.com
 */
function sendSystemNoticeForTrader($user, $title, $content, $extend = [])
{
    try{

        $message = new \App\Notifications\Messages\UserNotificationMessage($title, $content, $extend);

        \Illuminate\Support\Facades\Notification::send($user, new \App\Notifications\TraderNotification($message, false));

    } catch (\Exception $exception) {

        \report($exception);
    }

}

/**
 * 发送系统通知所有用户
 * @param string $title 标题
 * @param string $content 内容
 * @param array $extend 扩展参数
 * @author john1668@qq.com
 */
function sendSystemNoticeForAllUser($title, $content, $extend = [])
{
    try{

        $message = new \App\Notifications\Messages\UserNotificationMessage($title, $content, $extend);

        \Illuminate\Support\Facades\Notification::send(\App\Models\User::all(), new \App\Notifications\UserNotification($message));

    }catch (\Exception $exception) {

        \report($exception);
    }
}

/**
 * 发送系统通知所有用户(供应商)
 * @param string $title 标题
 * @param string $content 内容
 * @param array $extend 扩展参数
 * @author john1668@qq.com
 */
function sendSystemNoticeForAllTrader($title, $content, $extend = [])
{
    try{

        $message = new \App\Notifications\Messages\UserNotificationMessage($title, $content, $extend);

        \Illuminate\Support\Facades\Notification::send(\App\Models\Trader::all(), new \App\Notifications\TraderNotification($message));

    }catch (\Exception $exception) {

        \report($exception);
    }
}

/**
 * 发送系统通知平台
 * @param $title
 * @param $content
 * @param string $type
 * @param array $extend 扩展参数
 * @author john1668@qq.com
 */
function sendPlatformNotice($title, $content, $type, array $extend = [])
{
    try{
        $message = new \App\Notifications\Messages\UserNotificationMessage($title, $content, $extend);

        switch ($type) {
            case 'goods':
                $notification = new \App\Notifications\GoodsNotification($message, false);
                break;
            default:
                $notification = new \App\Notifications\SystemNotification($message, false);
        }

        \Illuminate\Support\Facades\Notification::send(\App\Models\AdminUser::find(1), $notification);

    }catch (\Exception $exception) {

        \report($exception);
    }
}

/*
 * 作用：用*号替代姓名除第一个字之外的字符
 * 参数：
 *
 *
 * 返回值：string
 */
function starNameReplace($name, $num = 0)
{
    if ($num && mb_strlen($name, 'UTF-8') > $num) {
        return mb_substr($name, 0, 4) . '*';
    }

    if ($num && mb_strlen($name, 'UTF-8') <= $num) {
        return $name;
    }

    $doubleSurname = [
        '欧阳', '太史', '端木', '上官', '司马', '东方', '独孤', '南宫',
        '万俟', '闻人', '夏侯', '诸葛', '尉迟', '公羊', '赫连', '澹台', '皇甫', '宗政', '濮阳',
        '公冶', '太叔', '申屠', '公孙', '慕容', '仲孙', '钟离', '长孙', '宇文', '司徒', '鲜于',
        '司空', '闾丘', '子车', '亓官', '司寇', '巫马', '公西', '颛孙', '壤驷', '公良', '漆雕', '乐正',
        '宰父', '谷梁', '拓跋', '夹谷', '轩辕', '令狐', '段干', '百里', '呼延', '东郭', '南门', '羊舌',
        '微生', '公户', '公玉', '公仪', '梁丘', '公仲', '公上', '公门', '公山', '公坚', '左丘', '公伯',
        '西门', '公祖', '第五', '公乘', '贯丘', '公皙', '南荣', '东里', '东宫', '仲长', '子书', '子桑',
        '即墨', '达奚', '褚师', '吴铭'
    ];

    $surname = mb_substr($name, 0, 2);

    if (mb_strlen($name, 'UTF-8') <= 0) {
        return $name;
    }

    if (in_array($surname, $doubleSurname)) {
        $name = mb_substr($name, 0, 2) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 2));
    } else {
        $name = mb_substr($name, 0, 1) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 1));
    }


    return $name;
}

/**
 * 产生随机字串，可用来自动生成密码
 * 默认长度6位 字母和数字混合 支持中文
 * @param string $len 长度
 * @param string $type 字串类型
 * 0 字母 1 数字 其它 混合
 * @param string $addChars 额外字符
 * @return string
 */
function randString($len=6,$type='',$addChars='') {
    $str ='';
    switch($type) {
        case 0:
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars;
            break;
        case 1:
            $chars= str_repeat('0123456789',3);
            break;
        case 2:
            $chars='ABCDEFGHIJKMNPQRSTUVWXYZ'.$addChars;
            break;
        case 3:
            $chars='abcdefghijkmnpqrstuvwxyz'.$addChars;
            break;
        case 4:
            $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars;
            break;
        case 5:
            $chars='abcdefghijkmnpqrstuvwxyz23456789';
            break;
        case 6:
            $chars='ABCDEFGHIJKMNPQRSTUVWXYZ23456789';
            break;
        default :
            // 默认去掉了容易混淆的字符oOLl和数字01，要添加请使用addChars参数
            $chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars;
            break;
    }
    if($len>10 ) {//位数过长重复字符串一定次数
        $chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5);
    }
    if($type!=4) {
        $chars   =   str_shuffle($chars);
        $str     =   substr($chars,0,$len);
    }else{
        // 中文随机字
        for($i=0;$i<$len;$i++){
            $str.= msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1,'utf-8',false);
        }
    }
    return $str;
}

/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
    if(function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif(function_exists('iconv_substr')) {
        $slice = iconv_substr($str,$start,$length,$charset);
    }else{
        $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("",array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice.'...' : $slice;
}

/** 二进制流生成文件
 * $_POST 无法解释二进制流，需要用到 $GLOBALS['HTTP_RAW_POST_DATA'] 或 php://input
 * $GLOBALS['HTTP_RAW_POST_DATA'] 和 php://input 都不能用于 enctype=multipart/form-data
 * @param    String  $file   要生成的文件路径
 * @return   boolean
 */
function binary_to_file($file){
    $content = $GLOBALS['HTTP_RAW_POST_DATA'];  // 需要php.ini设置
    if(empty($content)){
        $content = file_get_contents('php://input');    // 不需要php.ini设置，内存压力小
    }
    $ret = file_put_contents($file, $content, true);
    return $ret;
}

//判断是否是移动端访问
function isMobile(){
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) {
        return TRUE;
    }
    // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset ($_SERVER['HTTP_VIA'])) {
        return stristr($_SERVER['HTTP_VIA'], "wap") ? TRUE : FALSE;// 找不到为flase,否则为TRUE
    }
    // 判断手机发送的客户端标志,兼容性有待提高
    if (isset ($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array(
            'mobile',
            'nokia',
            'sony',
            'ericsson',
            'mot',
            'samsung',
            'htc',
            'sgh',
            'lg',
            'sharp',
            'sie-',
            'philips',
            'panasonic',
            'alcatel',
            'lenovo',
            'iphone',
            'ipod',
            'blackberry',
            'meizu',
            'android',
            'netfront',
            'symbian',
            'ucweb',
            'windowsce',
            'palm',
            'operamini',
            'operamobi',
            'openwave',
            'nexusone',
            'cldc',
            'midp',
            'wap'
        );
        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return TRUE;
        }
    }
    if (isset ($_SERVER['HTTP_ACCEPT'])) { // 协议法，因为有可能不准确，放到最后判断
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== FALSE) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === FALSE || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return TRUE;
        }
    }
    return FALSE;
}

/**
 * 指定字段按照某个顺序排序
 * @param $sort 排序方式 英文逗号隔开
 * @param $arr 排序的数组
 * @param $field 排序的字段
 * @return array|string
 */
function arraySort( $sort, $arr, $field) {
    if ( '' == $sort || 1 > count( $arr ) ) {
        return [];
    }
    $res = array();
    $sort = explode( ',', $sort );
    foreach ( $sort as $k=>$v ) {
        foreach ( $arr as $ky=>$ve ) {
            if ( $ve[$field] == $v ) {
                array_push( $res, $ve );
                unset( $arr[$ky] );
                break;
            }
        }
    }
    return $res;
}


/**
 * 获取客户端真实ip
 * @return mixed
 */
function _getRealIpAddr() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip=$_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { //to check ip is pass from proxy
        $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip=$_SERVER['REMOTE_ADDR'];
    }

    return $ip;
}

/**
 * 下载远程文件
 * @param string $file_url 下载文件地址
 * @param string $save_path 下载文件保存目录
 * @param string $file_name 下载文件保存名称
 * @return bool
 */
function curlDownFile($file_url, $save_path = '', $file_name = '') {

    // 没有远程url或已下载文件，返回false
    if (trim($file_url) == '' || file_exists( $save_path.$file_name )) {
        return false;
    }

    // 若没指定目录，则默认当前目录
    if (trim($save_path) == '') {
        $save_path = './';
    }

    // 若指定的目录没有，则创建
    if (!file_exists($save_path) && !mkdir($save_path, 0777, true)) {
        return false;
    }

    // 若没指定文件名，则自动命名
    if (trim($file_name) == '') {
        $file_ext = strrchr($file_url, '.');
//        $file_exts = array('.gif', '.jpg', '.png','mp3');
//        if (!in_array($file_ext, $file_exts)) {
//            return false;
//        }
        $file_name = time() . $file_ext;
    }
    // curl下载文件
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch, CURLOPT_ENCODING,'gzip');
    curl_setopt($ch, CURLOPT_URL, $file_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $file = curl_exec($ch);
    curl_close($ch);
//    // 使用中文文件名需要转码
//    $fp = fopen($save_path.iconv('UTF-8', 'GBK', $file_name),'w');
//    fwrite($fp, $file);
//    fclose($fp);
    // 保存文件到指定路径
//    file_put_contents($save_path.$file_name, $file);
    $img = file_get_contents("compress.zlib://".$file_url);
    $data = file_put_contents(public_path().'/'.$save_path.$file_name,$img);
    // 释放文件内存
    unset($file);
    // 执行成功，返回true
    return true;
}

/**
 * 将秒数转换为时间（年、天、小时、分、秒）
 * @param $time
 * @return bool|string
 */
function Sec2Time($time){
    if(is_numeric($time)){
        $value = array(
            "years" => 0, "days" => 0, "hours" => 0,
            "minutes" => 0, "seconds" => 0,
        );
        if($time >= 31556926){
            $value["years"] = floor($time/31556926);
            $time = ($time%31556926);
        }
        if($time >= 86400){
            $value["days"] = floor($time/86400);
            $time = ($time%86400);
        }
        if($time >= 3600){
            $value["hours"] = floor($time/3600);
            $time = ($time%3600);
        }
        if($time >= 60){
            $value["minutes"] = floor($time/60);
            $time = ($time%60);
        }
        $value["seconds"] = floor($time);
        //return (array) $value;
        $t=$value["years"] ."年". $value["days"] ."天"." ". $value["hours"] ."小时". $value["minutes"] ."分".$value["seconds"]."秒";
        Return $t;

    }else{
        return (bool) FALSE;
    }
}

/**
 * 将秒转换为 分:秒
 * s int 秒数
 */
function s_to_hs($s=0){
    //计算分钟
    //算法：将秒数除以60，然后下舍入，既得到分钟数
    $h    =    floor($s/60);
    //计算秒
    //算法：取得秒%60的余数，既得到秒数
    $s    =    $s%60;
    //如果只有一位数，前面增加一个0
    $h    =    (strlen($h)==1)?'0'.$h:$h;
    $s    =    (strlen($s)==1)?'0'.$s:$s;
    return $h.':'.$s;
}

/**
 * 生成订单号
 * @return string
 */
function getSn() {
    list($usec, $sec) = explode(" ",microtime());
    $sec = sprintf("%03d", (int)($usec * 1000));
    return date('YmdHis',time()).$sec.mt_rand(1000, 9999);
}

/**
 * 功能：隐藏转换*号
 * @param string $str
 * @param int $type 类型：1-手机；2-身份证；3-IP
 * @return mixed
 */
function searchAndReplace($str, $type = 1)
{
    if ($type == 1) {
        return preg_replace('/(^.*)\d{4}(\d{4})$/', '\\1****\\2', $str);
    } else if ($type == 2) {
        return strlen($str) == 15 ? substr_replace($str, "****", 8, 4) : (strlen($str) == 18 ? substr_replace($str, "****", 10, 4) : $str);
    } else if ($type == 3) {
        return preg_replace('/((?:\d+\.){3})\d+/', "\\1*", $str);
    }
}

/*
    * 阿里云 短信发送
    * data = [
    *    phone => ***,
    *    type => ***,
    *    data => ['变量1'=>***, '变量2'=>***, ...]
    * ]
    */
function aliyunSms($data)
{
    if (!config('sms.sms_status')) {
        return ['code'=>400, 'msg'=>'短信功能已关闭'];
    }
    $config = config('sms');
    $easySms = new EasySms($config);
    try {
        $easySms->send($data['mobile'], [
            'template' => config('sms.tmp.mb_'.$data['type']),
            'data' => $data['data']
        ]);
    } catch (\GuzzleHttp\Exception\ClientException $exception){
        $response = $exception->getResponse();
        $result = json_decode($response->getBody()->getContents(), true);
        return response()->json(['code'=>500, 'msg'=>$result['msg'] ? $result['msg'] :  '短信发送异常']);
        // return $this->response->errorInternal($result['msg'] ? $result['msg'] :  '短信发送异常');
    }

    return ['code'=>200, 'msg'=>'发送成功'];
}

/**
 * 文件下载
 * @param $url
 * @return mixed
 */
function fileDownload($url,$path=''){
    if ($path == '') {
        $path = 'message';
    }
    $date_name = date("Y-m-d");
    $up_dir = './storage/' . $path . '/' . $date_name . '/';
    create_dir($up_dir);
    ob_start(); //打开输出
    readfile($url); //输出文件
    $img = ob_get_contents(); //得到浏览器输出
    ob_end_clean(); //清除输出并关闭
    $data = explode('/',$url);
    $filename = array_pop($data);
    $new_file = $up_dir . $filename;
    if(file_put_contents($new_file, $img)){
        $img_url = ltrim(ltrim($new_file, '.'), '.');
        return ['code' => 0, 'msg' => '上传成功！', 'url' => $img_url];
    } else {
        return ['code' => 1, 'msg' => '上传失败！'];
    }
}

/**
 * gz 文件解压
 */
if (!function_exists('gzdecode')) {
    function gzdecode ($data)
    {
        $flags = ord(substr($data, 3, 1));
        $headerlen = 10;
        $extralen = 0;
        $filenamelen = 0;
        if ($flags & 4) {
            $extralen = unpack('v', substr($data, 10, 2));
            $extralen = $extralen[1];
            $headerlen += 2 + $extralen;
        }
        if ($flags & 8) // Filename
            $headerlen = strpos($data, chr(0), $headerlen) + 1;
        if ($flags & 16) // Comment
            $headerlen = strpos($data, chr(0), $headerlen) + 1;
        if ($flags & 2) // CRC at end of file
            $headerlen += 2;
        $unpacked = @gzinflate(substr($data, $headerlen));
        if ($unpacked === FALSE)
            $unpacked = $data;
        return $unpacked;
    }
}

/*
 * 作用：用*号替代姓名除第一个字之外的字符
 * 参数：
 * 返回值：string
 */
function starReplace($name, $num = 0)
{
    if ($num && mb_strlen($name, 'UTF-8') > $num) {
        return mb_substr($name, 0, 4) . '*';
    }

    if ($num && mb_strlen($name, 'UTF-8') <= $num) {
        return $name;
    }

    $doubleSurname = [
        '欧阳', '太史', '端木', '上官', '司马', '东方', '独孤', '南宫',
        '万俟', '闻人', '夏侯', '诸葛', '尉迟', '公羊', '赫连', '澹台', '皇甫', '宗政', '濮阳',
        '公冶', '太叔', '申屠', '公孙', '慕容', '仲孙', '钟离', '长孙', '宇文', '司徒', '鲜于',
        '司空', '闾丘', '子车', '亓官', '司寇', '巫马', '公西', '颛孙', '壤驷', '公良', '漆雕', '乐正',
        '宰父', '谷梁', '拓跋', '夹谷', '轩辕', '令狐', '段干', '百里', '呼延', '东郭', '南门', '羊舌',
        '微生', '公户', '公玉', '公仪', '梁丘', '公仲', '公上', '公门', '公山', '公坚', '左丘', '公伯',
        '西门', '公祖', '第五', '公乘', '贯丘', '公皙', '南荣', '东里', '东宫', '仲长', '子书', '子桑',
        '即墨', '达奚', '褚师', '吴铭'
    ];

    $surname = mb_substr($name, 0, 2);
    if (in_array($surname, $doubleSurname)) {
        $name = mb_substr($name, 0, 2) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 2));
    } else {
        $name = mb_substr($name, 0, 1) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 1));
    }


    return $name;
}

/**
+----------------------------------------------------------
 * 将一个字符串部分字符用*替代隐藏
+----------------------------------------------------------
 * @param string $string 待转换的字符串
 * @param int  $bengin 起始位置，从0开始计数，当$type=4时，表示左侧保留长度
 * @param int  $len  需要转换成*的字符个数，当$type=4时，表示右侧保留长度
 * @param int  $type  转换类型：0，从左向右隐藏；1，从右向左隐藏；2，从指定字符位置分割前由右向左隐藏；3，从指定字符位置分割后由左向右隐藏；4，保留首末指定字符串
 * @param string $glue  分割符
+----------------------------------------------------------
 * @return string 处理后的字符串
+----------------------------------------------------------
 */
function hideStr($string, $bengin = 0, $len = 4, $type = 0, $glue = "@") {
    if (empty($string))
        return false;
    $array = array();
    if ($type == 0 || $type == 1 || $type == 4) {
        $strlen = $length = mb_strlen($string);
        while ($strlen) {
            $array[] = mb_substr($string, 0, 1, "utf8");
            $string = mb_substr($string, 1, $strlen, "utf8");
            $strlen = mb_strlen($string);
        }
    }
    if ($type == 0) {
        for ($i = $bengin; $i < ($bengin + $len); $i++) {
            if (isset($array[$i]))
                $array[$i] = "*";
        }
        $string = implode("", $array);
    } else if ($type == 1) {
        $array = array_reverse($array);
        for ($i = $bengin; $i < ($bengin + $len); $i++) {
            if (isset($array[$i]))
                $array[$i] = "*";
        }
        $string = implode("", array_reverse($array));
    } else if ($type == 2) {
        $array = explode($glue, $string);
        $array[0] = hideStr($array[0], $bengin, $len, 1);
        $string = implode($glue, $array);
    } else if ($type == 3) {
        $array = explode($glue, $string);
        $array[1] = hideStr($array[1], $bengin, $len, 0);
        $string = implode($glue, $array);
    } else if ($type == 4) {
        $left = $bengin;
        $right = $len;
        $tem = array();
        for ($i = 0; $i < ($length - $right); $i++) {
            if (isset($array[$i]))
                $tem[] = $i >= $left ? "*" : $array[$i];
        }
        $array = array_chunk(array_reverse($array), $right);
        $array = array_reverse($array[0]);
        for ($i = 0; $i < $right; $i++) {
            $tem[] = $array[$i];
        }
        $string = implode("", $tem);
    }
    return $string;
}

//删除空格和回车
function trimall($str){
    $qian=array(" ","　","\t","\n","\r");
    return str_replace($qian, '', $str);
}